"""
Case Type   : 资源池化故障模式库
Case Name   : pid文件无权限-postmaster.pid文件无读写权限，停止数据库
Create At   : 2025/04
Owner       : haomeng
Description :
    1、查看集群状态
    2、运行tpcc业务
    3、修改主节点postmaster.pid文件权限为不可访问
    4、查看业务运行情况
    5、重启集群
    6、查看集群状态，查看postmaster.pid文件是否存在
    7、修改原主节点postmaster.pid文件权限为可访问
    8、拉起被踢出节点
    9、查看集群状态,检查postmaster.pid文件权限是否正常
    10、恢复环境初始状态
Expect      :
    1、集群状态正常
    2、运行业务成功
    3、修改主节点postmaster.pid文件权限成功
    4、业务运行正常无影响
    5、重启集群失败
    6、集群状态异常,原主节点被踢出，其他存活节点正常
    7、修改原主节点postmaster.pid文件权限成功
    8、拉起被踢出节点成功
    9、集群状态正常，postmaster.pid文件权限正常
    10、恢复环境初始状态成功
History     :
"""

import os
import time
import unittest

from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.ComThread import ComThread
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro

class SSFauleMode(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'----{os.path.basename(__file__)} start----')
        self.user_node = [Node(node='PrimaryRoot'), Node(node='PrimaryDbUser')]
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.com = Common()
        self.constant = Constant()
        self.pid_file = os.path.join(macro.DB_INSTANCE_PATH, macro.PID_FILE_NAME)

    def test_ss_faule(self):
        text = '-----step1:查看集群状态;  expect:集群状态正常-----'
        self.log.info(text)

        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertIn('Normal', status, '集群状态异常')

        text = '-----step2:执行tpcc读写业务  expect:业务执行成功-----'
        self.log.info(text)

        tpcc_cmd = f'./runBenchmark.sh {macro.PROPS_FILENAME}'
        self.log.info(tpcc_cmd)

        tpcc_execute = ComThread(self.com.start_tpcc, args=(self.user_node[0],
                                                               f'{macro.TPCC_PATH}',
                                                               tpcc_cmd))
        tpcc_execute.setDaemon(True)
        tpcc_execute.start()

        text = '-----step3:修改主节点postmaster.pid文件权限为不可访问  expect:修改权限成功-----'
        self.log.info(text)

        chmod = f"chmod 000 {self.pid_file};ls -al {self.pid_file};"
        self.log.info(chmod)

        chmod_execute = ComThread(self.com.get_sh_result, args=(self.user_node[1], chmod))
        chmod_execute.setDaemon(True)
        chmod_execute.start()

        text = '-----step4:查看业务运行情况  expect:业务运行正常无影响-----'
        self.log.info(text)

        tpcc_execute.join(10 * 60)
        ret1 = tpcc_execute.get_result()
        self.log.info(ret1)
        self.assertIn('Session End', ret1, 'tpcc执行失败')

        chmod_execute.join(10 * 60)
        ret2 = chmod_execute.get_result()
        self.log.info(ret2)
        self.assertIn('----------', ret2, '修改postmaster.pid文件失败')

        text = '-----step5:重启集群  expect:启动失败-----'
        self.log.info(text)

        restart = self.pri_sh.exec_cm_ctl('stop;','cm_ctl start -t 30')
        self.log.info(restart)
        self.assertIn(self.constant.cm_stop_success_msg, restart, '停止集群失败')
        self.assertIn(self.constant.cm_start_failed_msg, restart, '启动集群成功')

        text = '-----step6:查看集群状态  expect:集群状态异常，原主节点被踢出-----'
        self.log.info(text)

        time.sleep(30)
        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertIn('P Down', status.splitlines()[-1].split('|')[0], '集群状态正常')
        self.assertIn('S Primary', status, '存活节点状态异常')

        text = '-----step7:修改原主节点postmaster.pid文件权限为可访问  expect:修改权限成功-----'
        self.log.info(text)

        chmod = f"chmod 600 {self.pid_file};ls -al {self.pid_file};"
        self.log.info(chmod)
        res = self.user_node[1].sh(chmod).result()
        self.log.info(res)
        self.assertIn('rw', res, '修改postmaster.pid文件权限失败')

        text = '-----step8:拉起被踢出节点  expect:拉起成功-----'
        self.log.info(text)

        start = self.pri_sh.exec_cm_ctl('start')
        self.log.info(start)
        self.assertIn(self.constant.cm_start_success_msg, start, '启动集群失败')

        text = '-----step9:查看集群状态  expect:集群状态正常，postmaster.pid文件权限正常-----'
        self.log.info(text)

        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertIn('Normal', status, '集群状态异常')

        check = f'ls -al {self.pid_file}'
        self.log.info(check)
        res = self.user_node[1].sh(check).result()
        self.log.info(res)
        self.assertIn('rw', res, 'postmaster.pid文件权限异常')

    def tearDown(self):
        text = '-----step10:恢复环境初始状态  expect:恢复成功-----'
        self.log.info(text)

        if 'P Primary' not in self.pri_sh.exec_cm_ctl('query', '-Cv'):
            switch = self.pri_sh.exec_cm_ctl('switchover', '-a')
            self.log.info(switch)

        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertIn('Normal', status, '集群状态异常')
        self.assertIn('P Primary', status, '集群状态异常')
        self.log.info(f'----{os.path.basename(__file__)} end----')
